﻿using GalaSoft.MvvmLight.Command;
using KJSyncXP.Extensions;
using KJSyncXP.Services;
using KJSyncXP.Sync.Services;
using KJSyncXP.Views.pop;
using log4net.Repository.Hierarchy;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;

namespace KJSyncXP.ViewModels
{
    public class MainWindowViewModel : BaseViewModel
    {
        private readonly log4net.ILog _logger;

        private readonly AppConfig _appConfig;
        public System.Timers.Timer MesStandardToSqliteSyncTimer { get; private set; }
        //public System.Timers.Timer SqliteStandardToAccessSyncTimer { get; private set; }
        public System.Timers.Timer SqliteStandardToFileSyncTimer { get; private set; }
        public System.Timers.Timer AccessToSqliteSyncTimer { get; private set; }
        public System.Timers.Timer SqliteToMesSyncTimer { get; private set; }

        public AccessSqliteSyncService _accessSqliteSyncService { get; private set; }
        public OracleSqliteSyncService _oracleSqliteSyncService { get; private set; }
        public SqliteToFileSyncService  _sqliteToFileSyncService { get; private set; }

        //Mes标准同步数据表
        private static readonly SemaphoreSlim MesStandardToSqliteSemaphore = new SemaphoreSlim(1, 1);
        //Sqlite标准同步数据表
        //private static readonly SemaphoreSlim SqliteStandardToAccessSemaphore = new SemaphoreSlim(1, 1);

        //Sqlite标准同步到文件
        private static readonly SemaphoreSlim SqliteStandardToFileSemaphore = new SemaphoreSlim(1, 1);

        //硫化机Access检测数据同步到Sqlite
        private static readonly SemaphoreSlim AccessToSqliteSemaphore = new SemaphoreSlim(1, 1);
        //Sqlite数据同步到Mes
        private static readonly SemaphoreSlim SqliteToMesSemaphore = new SemaphoreSlim(1, 1);



        // 操作员属性（绑定状态栏UI）
        private string _currentOperator;
        public string CurrentOperator
        {
            get => _currentOperator;
            set
            {
                _currentOperator = value;
                RaisePropertyChanged(nameof(CurrentOperator)); // 通知UI更新
            }
        }


        // 单个 AppConfig 对象
        private AppConfig _appConfigData;
        public AppConfig AppConfigData
        {
            get => _appConfigData;
            set
            {
                _appConfigData = value;
                RaisePropertyChanged("AppConfigData"); // 通知UI属性变更
            }
        }

        public StandardViewModel _standardViewModel { get; set; }

        public LoginViewModel _loginViewModel { get; set; }

        // 声明命令
        public RelayCommand ShowLoginWindowCommand { get; private set; }


        public MainWindowViewModel(log4net.ILog log, AppConfig appConfig, AccessSqliteSyncService accessSqliteSyncService, 
            OracleSqliteSyncService oracleSqliteSyncService, SqliteToFileSyncService sqliteToFileSyncService, 
            StandardViewModel standardViewModel,LoginViewModel loginViewModel)
        {
            _logger = log;
            _appConfig = appConfig;
            _accessSqliteSyncService = accessSqliteSyncService;
            _oracleSqliteSyncService = oracleSqliteSyncService;
            _sqliteToFileSyncService = sqliteToFileSyncService;
            _standardViewModel = standardViewModel;
            _loginViewModel = loginViewModel;

            ShowLoginWindowCommand = new RelayCommand(ShowLoginWindow);

            // 关键：订阅AppConfig的属性变化事件
            //_appConfig.PropertyChanged += AppConfig_PropertyChanged;

            // 监听 AuthenticationManager 的登录状态变化（如登录/注销后同步）
            AuthenticationManager.Instance.PropertyChanged += (sender, e) =>
            {
                // 当 LoginName 变化时（登录/注销），重新同步操作员名称
                if (e.PropertyName == nameof(AuthenticationManager.LoginName))
                {
                    SyncLoginUser();
                }
            };

            loadAppConfig();

            // 这里处理定任务
            InitializeTask();

        }

        #region 数据同步

        private void InitializeTask()
        {
            // 修改这里的时间取配置参数
            MesStandardToSqliteSyncTimer = new System.Timers.Timer();
            MesStandardToSqliteSyncTimer.Elapsed += MesStandardToSqliteSyncTimer_Elapsed;
            MesStandardToSqliteSyncTimer.Interval = 1*100000* 1000;//60秒
            //MesStandardToSqliteSyncTimer.Start();


            /*  SqliteStandardToAccessSyncTimer = new System.Timers.Timer();
              SqliteStandardToAccessSyncTimer.Elapsed += SqliteStandardToAccessSyncTimer_Elapsed;
              SqliteStandardToAccessSyncTimer.Interval = 1 * 100000 * 1000;//60秒
              SqliteStandardToAccessSyncTimer.Start();*/

            SqliteStandardToFileSyncTimer = new System.Timers.Timer();
            SqliteStandardToFileSyncTimer.Elapsed += SqliteStandardToFileSyncTimer_Elapsed;
            SqliteStandardToFileSyncTimer.Interval = 1 * 100000 * 1000;//60秒
            //SqliteStandardToFileSyncTimer.Start();



            AccessToSqliteSyncTimer = new System.Timers.Timer();
            AccessToSqliteSyncTimer.Elapsed += AccessToSqliteSyncTimer_Elapsed;
            AccessToSqliteSyncTimer.Interval = _appConfig.SyncTime * 1000;
            AccessToSqliteSyncTimer.Start();


            SqliteToMesSyncTimer = new System.Timers.Timer();
            SqliteToMesSyncTimer.Elapsed += SqliteToMesSyncTimer_Elapsed;
            SqliteToMesSyncTimer.Interval = _appConfig.SyncTime * 1000;
            SqliteToMesSyncTimer.Start();


            //启动时先处理一次
            Task.Factory.StartNew(() =>
            {
                //SqliteStandardToFileSyncTimer_Elapsed(null,null);
                //SqliteToMesSyncTimer_Elapsed(null,null);
                //AccessToSqliteSyncTimer_Elapsed(null, null);
                //MesStandardToSqliteSyncTimer_Elapsed(null, null);
                //SqliteStandardToAccessSyncTimer_Elapsed(null, null);
            });
        }

        /// <summary>
        /// 定期Mes标准同步数据到Sqlite
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void MesStandardToSqliteSyncTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 尝试同步地获取信号量，不等待
            bool lockAcquired = MesStandardToSqliteSemaphore.Wait(0);
            if (!lockAcquired)
            {
                _logger.Warn("同步任务已在运行，跳过此次调用。");
                return;
            }
            try
            {
                _oracleSqliteSyncService.GetMesTestStandard();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"MesStandardToSqliteSyncTimer_Elapsed:定期获取Mes标准数据发生异常:{ex.Message}");
                _logger.Error($"定期获取Mes标准数据发生异常:{ex.Message}{ex.StackTrace}", ex);
                MesStandardToSqliteSemaphore.Release();
            }
        }


        /// <summary>
        /// 定期Sqlite标准同步数据到Access
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
       /* private void SqliteStandardToAccessSyncTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 尝试同步地获取信号量，不等待
            bool lockAcquired = SqliteStandardToAccessSemaphore.Wait(0);
            if (!lockAcquired)
            {
                _logger.Warn("同步任务已在运行，跳过此次调用。");
                return;
            }
            try
            {
                _accessSqliteSyncService.PullTestStandardToAccess();
                _standardViewModel.LoadBas001();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"SqliteStandardToAccessSyncTimer_Elapsed:推送标准到Access发生异常:{ex.Message}");
                _logger.Error($"推送标准到Access发生异常:{ex.Message}{ex.StackTrace}", ex);
                SqliteStandardToAccessSemaphore.Release();
            }
        }*/


        /// <summary>
        /// 定期Sqlite标准同步数据修改、生成.id文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SqliteStandardToFileSyncTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 尝试同步地获取信号量，不等待
            bool lockAcquired = SqliteStandardToFileSemaphore.Wait(0);
            if (!lockAcquired)
            {
                _logger.Warn("同步任务已在运行，跳过此次调用。");
                return;
            }
            try
            {
                _sqliteToFileSyncService.PullTestStandardToFile();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"SqliteStandardToFileSyncTimer_Elapsed:推送标准到ID文件发生异常:{ex.Message}");
                _logger.Error($"推送标准到ID文件发生异常:{ex.Message}{ex.StackTrace}", ex);
                SqliteStandardToFileSemaphore.Release();
            }
        }

        /// <summary>
        /// 定期获取Access检测数同步到Sqlite
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void AccessToSqliteSyncTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 尝试同步地获取信号量，不等待
            bool lockAcquired = AccessToSqliteSemaphore.Wait(0);
            if (!lockAcquired)
            {
                _logger.Warn("获取Access检测数据到Sqlite同步任务已在运行，跳过此次调用。");
                return;
            }
            try
            {
                _accessSqliteSyncService.GetAccessDat200RhToSqlite();              
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"AccessToSqliteSyncTimerr_Elapsed:获取Access检测数据发生异常:{ex.Message}");
                _logger.Error($"获取Access检测数据发生异常:{ex.Message}{ex.StackTrace}", ex);
            }
            finally
            {
                // 无论是否发生异常，最终都释放信号量
                if (lockAcquired)
                {
                    AccessToSqliteSemaphore.Release();
                }
            }
        }

        /// <summary>
        /// 定期获取Sqlite检测数据同步到Mes
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void SqliteToMesSyncTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            // 尝试同步地获取信号量，不等待
            bool lockAcquired = SqliteToMesSemaphore.Wait(0);
            if (!lockAcquired)
            {
                _logger.Warn("获取Sqlite检测数据到Mes同步任务已在运行，跳过此次调用。");
                return;
            }
            try
            {
                _oracleSqliteSyncService.PullDatRH200ToMes();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"SqliteToMesSyncTimer_Elapsed:获取Sqlite检测数据发生异常:{ex.Message}");
                _logger.Error($"获取Sqlite检测数据发生异常:{ex.Message}{ex.StackTrace}", ex);
            }
            finally
            {
                // 无论是否发生异常，最终都释放信号量
                if (lockAcquired)
                {
                    SqliteToMesSemaphore.Release();
                }
            }
        }


        #endregion


        #region 登录+配置相关操作

        // 同步 Session 中的登录用户到 CurrentOperator
        private void SyncLoginUser()
        {
            var authManager = AuthenticationManager.Instance;
            // 若已登录，显示用户名；未登录，显示“未登录”
            CurrentOperator = !string.IsNullOrEmpty(authManager.LoginName)
                ? authManager.LoginName
                : "未登录";
        }


        public void loadAppConfig()
        {
            try
            {
                // 直接赋值单个 AppConfig 对象
                AppConfigData = _appConfig;
            }
            catch (Exception ex)
            {
                _logger.Warn("加载配置失败", ex);
            }
        }

        // 处理AppConfig的属性变化
        private void AppConfig_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            // 当AppConfig的CurrentUser属性变化时，更新CurrentOperator
            if (e.PropertyName == nameof(AppConfig.CurrentUser))
            {
                UpdateCurrentOperator();
            }
        }
        // 更新操作员文本（从AppConfig.CurrentUser获取值）
        private void UpdateCurrentOperator()
        {
            CurrentOperator = string.IsNullOrWhiteSpace(_appConfig.CurrentUser)
                ? string.Empty
                : _appConfig.CurrentUser;

            // 日志：记录操作员变化
            _logger.Info($"当前操作员更新为：{CurrentOperator ?? "未登录"}");
        }



        private void ShowLoginWindow()
        {
            var loginWindow = new LoginWindow(_loginViewModel);
            loginWindow.ShowDialog();
        } 


        #endregion
    }
}
